home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Mousetools / MouseBlanker / MouseBlanker.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  54KB  |  1,633 lines

  1. /*
  2.  *  MouseBlanker.c
  3.  *
  4.  *  Commodity
  5.  *
  6.  *  Author: Stefan Sticht
  7.  *
  8.  *  Copyright: source is public domain, no copyright
  9.  *
  10.  *  Version history:
  11.  *
  12.  *  V1.00   initial release
  13.  *  V1.03   added window
  14.  *  V1.04   recompiled with window.c V1.01
  15.  *  V1.05   recompiled with window.c V1.02
  16.  *  V1.06   recompiled with main.c V1.02
  17.  *  V1.07   completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
  18.  *  V1.08   now uses Stricmp from utility.library
  19.  *  V1.09   changed parameter parsing
  20.  *  V1.10   changed parameter parsing; introduced an error with V1.09
  21.  *  V1.11   a minor change
  22.  *  V1.12   replaced menu by gadtools underscores & vanillakeys
  23.  *          added blanking on key option
  24.  *          disables inputevent-filters if not needed
  25.  *  V1.13   added some LockIBase() where needed
  26.  *  V1.14   recompiled with changed (for 68040 compatiblity) cback.o
  27.  *  V1.15   major rework: changed mouse blanking method; added keypresses-feature
  28.  *                        many other changes
  29.  *  V1.16   added a pointer to a chip-memory-region in simplesprite.posctldata for GetSprite()
  30.  *          because it is not documented that GetSprite will handle a NULL in this field
  31.  *  V1.17   small changes
  32.  *  V1.18   removed enforcer hit under low mem in createallgadgets()
  33.  *          now window opens on the front screen, if it is a public screen, else on
  34.  *          the default public screen
  35.  *  V1.19 14 Sep 1991 Stefan Sticht some small changes to reduce code size
  36.  *  V1.20 16 Sep 1991 Stefan Sticht removed error in lockfrontpubscr()
  37.  *  V1.21 Mon 07-Oct-91 Stefan Sticht removed obsolete code: replying IDCMP messages before CloseWindow()
  38.  */
  39.  
  40. #define VERSION "V1.21"
  41.  
  42. /********************************************************************
  43.  *                             interfacing                          *
  44.  ********************************************************************/
  45.  
  46. /*
  47.  *  include files
  48.  */
  49. #include <math.h>
  50. #include <stdarg.h>
  51. #include <stdlib.h>
  52. #include <string.h>
  53. #include <devices/inputevent.h>
  54. #include <exec/memory.h>
  55. #include <intuition/intuitionbase.h>
  56. #include <libraries/commodities.h>
  57.  
  58. #include <clib/alib_protos.h>
  59. #include <clib/commodities_protos.h>
  60. #include <pragmas/commodities_pragmas.h>
  61. #include <clib/dos_protos.h>
  62. #include <pragmas/dos_pragmas.h>
  63. #include <clib/exec_protos.h>
  64. #include <pragmas/exec_pragmas.h>
  65. #include <clib/gadtools_protos.h>
  66. #include <pragmas/gadtools_pragmas.h>
  67. #include <clib/graphics_protos.h>
  68. #include <pragmas/graphics_pragmas.h>
  69. #include <clib/intuition_protos.h>
  70. #include <pragmas/intuition_pragmas.h>
  71. #include <clib/utility_protos.h>
  72. #include <pragmas/utility_pragmas.h>
  73.  
  74. #ifdef DEBUG
  75. #define printf KPrintF
  76. #include <clib/dlib_protos.h>
  77. #endif
  78.  
  79. /*
  80.  *  prototypes
  81.  */
  82. long openwindow(void);
  83. struct Gadget *createallgadgets(struct Gadget **glist, APTR vi, struct Screen *scr, ULONG *height, ULONG *width);
  84. struct Library *myopenlibrary(char *name, unsigned long version);
  85. struct Screen *lockfrontpubscr(void);
  86. unsigned short command(unsigned short cmd);
  87. void __saveds keymon(void);
  88. void __saveds mousemon(void);
  89. void __saveds timermon(void);
  90. void blankmouse(short mode);
  91. void closewindow(void);
  92. void getkeypresses(void);
  93. void getseconds(void);
  94. void processmessages(short window);
  95. void unblankmouse(void);
  96.  
  97. /*
  98.  *  libraries opened by startup code; basepointers needed by function pragmas
  99.  */
  100. extern struct Library *DOSBase;
  101. extern struct Library *SysBase;
  102.  
  103. /*
  104.  *  Disable SAS/C CTRL/C handling
  105.  */
  106. void chkabort(void) {}
  107.  
  108. /********************************************************************
  109.  *                             global data                          *
  110.  ********************************************************************/
  111.  
  112. /*
  113.  *  definition of all messages
  114.  */
  115. #if defined(GERMAN)
  116.  
  117. #define RETRY_GADGETS               "Wiederholen|Abbrechen"
  118. #define RESUME_GADGETS              "Weiter"
  119. #define MSG_LIBRARY_OPENERR         "Die %s (V%ld+) kann nicht geöffnet werden!"
  120. #define MSG_WINDOW_OPENERR          "Leider kann das Fenster nicht geöffnet werden!"
  121. #define COM_NAME                    "Mausweg"
  122. #define COM_DESCR                   "Versteckt Mauszeiger"
  123. #define MSG_PROJECT                 "Projekt"
  124. #define MSG_SECONDS                 "_Sekunden:"
  125. #define MSG_SECONDS_SCC             'S'
  126. #define MSG_KEY                     "_Tastendrücke:"
  127. #define MSG_KEY_SCC                 'T'
  128. #define MSG_HIDE                    "_Verstecken"
  129. #define MSG_HIDE_SCC                'V'
  130. #define MSG_QUIT                    "_Beenden"
  131. #define MSG_QUIT_SCC                'B'
  132. #define YES                         "JA"
  133. #define NO                          "NEIN"
  134. #define TT_TIMEOUT                  "SEKUNDEN"
  135. #define TT_KEY                      "TASTENDRUECKE"
  136. #define TT_REBLANK                  "WIEDERHOLUNG"
  137.  
  138. /*
  139. #elif defined(???)  insert your language here!
  140.  */
  141.  
  142. #else
  143.  
  144. #define RETRY_GADGETS               "Retry|Cancel"
  145. #define RESUME_GADGETS              "Resume"
  146. #define MSG_LIBRARY_OPENERR         "%s (V%ld+) can't be opened!"
  147. #define MSG_WINDOW_OPENERR          "Window can't be opened!"
  148. #define COM_NAME                    "MouseBlanker"
  149. #define COM_DESCR                   "Blanks mouse pointer"
  150. #define MSG_PROJECT                 "Project"
  151. #define MSG_SECONDS                 "_Seconds:"
  152. #define MSG_SECONDS_SCC             'S'
  153. #define MSG_KEY                     "_Keypresses:"
  154. #define MSG_KEY_SCC                 'K'
  155. #define MSG_HIDE                    "_Hide"
  156. #define MSG_HIDE_SCC                'H'
  157. #define MSG_QUIT                    "_Quit"
  158. #define MSG_QUIT_SCC                'Q'
  159. #define YES                         "YES"
  160. #define NO                          "NO"
  161. #define TT_TIMEOUT                  "SECONDS"
  162. #define TT_KEY                      "KEYPRESSES"
  163. #define TT_REBLANK                  "REBLANKTIMEOUT"
  164.  
  165. #endif
  166.  
  167. /*
  168.  *  some constants
  169.  */
  170. #define COM_TITLE                   COM_NAME " " VERSION
  171. #define CX_PRIORITY                 "CX_PRIORITY"
  172. #define DEF_CX_PRIORITY             0
  173. #define CX_POPKEY                   "CX_POPKEY"
  174. #define DEF_CX_POPKEY               ""
  175. #define CX_POPUP                    "CX_POPUP"
  176. #define DEF_CX_POPUP                NO
  177. #define DEF_TIMEOUT                 3
  178. #define DEF_KEY                     5
  179. #define DEF_REBLANK                 2
  180. /*
  181.  *  with this ID we identify messages of our hotkey
  182.  */
  183. #define POP_KEY_ID                  100
  184.  
  185. /*
  186.  *  because there are several ways to initiate same functions
  187.  *  every way initiates a command which is processed later
  188.  */
  189. #define CCMD_NOP                    0
  190. #define CCMD_QUIT                   1
  191. #define CCMD_SECONDS                2
  192. #define CCMD_KEYPRESSES             3
  193. #define CCMD_SECONDS_ACTIVATE       4
  194. #define CCMD_KEYPRESSES_ACTIVATE    5
  195. #define CCMD_OPENWINDOW             6
  196. #define CCMD_CLOSEWINDOW            7
  197.  
  198. /*
  199.  *  short-cuts by underscored gadgets shall be case-insensitive
  200.  */
  201. #define CASE_DIFF   ('a' - 'A')
  202. /*
  203.  *  to make ActivateCxObj() more readable
  204.  */
  205. #define ON  1l
  206. #define OFF 0l
  207.  
  208. /*
  209.  *  data for SAS/C cback.o
  210.  */
  211. long _stack = 4096l;
  212. char *_procname = COM_NAME;
  213. long _priority = 0l;
  214. long _BackGroundIO = 1;
  215. extern BPTR _Backstdout;
  216.  
  217. /*
  218.  *  library base pointers
  219.  */
  220. struct IntuitionBase *IntuitionBase;
  221. struct Library *CxBase;
  222. struct Library *IconBase;
  223. struct Library *GadToolsBase;
  224. struct Library *GfxBase;
  225. struct Library *UtilityBase;
  226.  
  227. /*
  228.  *  ponter to our task's Task structure
  229.  */
  230. struct Task *mytask;
  231.  
  232. /*
  233.  *  signal we AllocSignal() in main()
  234.  */
  235. long signal = -1l;
  236.  
  237. /*
  238.  *  pointer to timerequest
  239.  */
  240. struct timerequest *timereq;
  241. short requestout = FALSE;
  242.  
  243. /*
  244.  *  message ports
  245.  */
  246. struct MsgPort *idcmpport;
  247. struct MsgPort *msgport;
  248.  
  249. /*
  250.  *  signal flags
  251.  */
  252. unsigned long customsigflag;
  253. unsigned long cxsigflag;
  254. unsigned long idcmpsigflag;
  255.  
  256. /*
  257.  *  programtitle and version for Version command
  258.  */
  259. char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
  260.  
  261. /*
  262.  *  helpstring
  263.  */
  264. #if defined(GERMAN)
  265. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
  266.                     "Aufruf: " COM_NAME " [" CX_PRIORITY "=<Zahl>] [" CX_POPKEY "=<Zeichenkette>] ["
  267.                     CX_POPUP "=" YES "|" NO "] [" TT_TIMEOUT "=<Zahl>] ["\
  268.                     TT_KEY "=<Zahl>] [" TT_REBLANK "=<Zahl>]\n";
  269. /*
  270. #elif defined(???)
  271. */
  272. #else
  273. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
  274.                     "Usage: " COM_NAME " [" CX_PRIORITY "=<number>] [" CX_POPKEY "=<string>] ["
  275.                     CX_POPUP "=" YES "|" NO "] [" TT_TIMEOUT "=<number>] ["\
  276.                     TT_KEY "=<number>] [" TT_REBLANK "=<number>]\n";
  277. #endif
  278.  
  279. /*
  280.  *  timeout values
  281.  */
  282. unsigned short timeout;
  283. unsigned short timeoutseconds;
  284. unsigned short timeoutperiod;
  285. unsigned short keys;
  286. unsigned short keypresses;
  287. unsigned short reblank;
  288.  
  289. /*
  290.  *  some constants for blanking the pointer
  291.  */
  292. #define NORMAL          0
  293. #define FORCE           1
  294. #define UNBLANKED       0
  295. #define BLANKED         1
  296. #define UNBLANK         0
  297. #define BLANK           1
  298. #define MOUSEBLANKED    (blankstatus == BLANKED)
  299. #define MOUSENOTBLANKED (blankstatus == UNBLANKED)
  300. unsigned char blankstatus  = UNBLANKED;
  301. unsigned char blankrequest = UNBLANK;
  302.  
  303. struct SimpleSprite simplesprite = {
  304.     NULL,   /* UWORD *posctldata; filled later  */
  305.     0,      /* UWORD height;                    */
  306.     0, 0,   /* UWORD x,y; current position      */
  307.     0       /* UWORD num;                       */
  308.     };
  309.  
  310. /*
  311.  *  the tooltypearray
  312.  */
  313. char **tooltypes;
  314.  
  315. /*
  316.  *  pointers to our commodities objects
  317.  */
  318. CxObj *broker = NULL;
  319. CxObj *hotkeyfilter;
  320. CxObj *mousefilter;
  321. CxObj *timerfilter;
  322. CxObj *keyfilter;
  323.  
  324. struct NewBroker newbroker = {
  325.     NB_VERSION,                         /* BYTE nb_Version               */
  326.     COM_NAME,                           /* BYTE *nb_Name                 */
  327.     COM_TITLE,                          /* BYTE *nb_Title                */
  328.     COM_DESCR,                          /* BYTE *nb_Descr                */
  329.     NBU_NOTIFY | NBU_UNIQUE,            /* SHORT nb_Unique               */
  330.     COF_SHOW_HIDE,                      /* SHORT nb_Flags                */
  331.     0,                                  /* BYTE nb_Pri                   */
  332.     NULL,                               /* struct MsgPort nb_Port        */
  333.     0                                   /* WORD nb_ReservedChannel       */
  334.     };
  335.  
  336. /*
  337.  *  some filters for filtering input events
  338.  */
  339. IX timerix = {
  340.     IX_VERSION,                         /* UBYTE ix_version     */
  341.     IECLASS_TIMER,                      /* UBYTE ix_Class       */
  342.     0,                                  /* UWORD ix_Code        */
  343.     0,                                  /* UWORD ix_CodeMask    */
  344.     0,                                  /* UWORD ix_Qualifier   */
  345.     0,                                  /* UWORD ix_Qualmask    */
  346.     0                                   /* UWORD ix_QualSame    */
  347.     };
  348.  
  349. IX mouseix = {
  350.     IX_VERSION,                         /* UBYTE ix_version     */
  351.     IECLASS_RAWMOUSE,                   /* UBYTE ix_Class       */
  352.     0,                                  /* UWORD ix_Code        */
  353.     0,                                  /* UWORD ix_CodeMask    */
  354.     IEQUALIFIER_RELATIVEMOUSE,          /* UWORD ix_Qualifier   */
  355.     IEQUALIFIER_RELATIVEMOUSE,          /* UWORD ix_Qualmask    */
  356.     0                                   /* UWORD ix_QualSame    */
  357.     };
  358.  
  359. /*
  360.  *  we only want to know of key releases
  361.  */
  362. IX keyix = {
  363.     IX_VERSION,                         /* UBYTE ix_version     */
  364.     IECLASS_RAWKEY,                     /* UBYTE ix_Class       */
  365.     0,                                  /* UWORD ix_Code        */
  366.     IECODE_UP_PREFIX,                   /* UWORD ix_CodeMask    */
  367.     0,                                  /* UWORD ix_Qualifier   */
  368.     IEQUALIFIER_REPEAT,                 /* UWORD ix_Qualmask    */
  369.     0                                   /* UWORD ix_QualSame    */
  370.     };
  371.  
  372. /*
  373.  *  data for our window
  374.  */
  375. struct Window *win;
  376. APTR vi;
  377. struct Gadget *gadgetlist;
  378. struct Screen *scr;
  379. char windowtitle[] = COM_TITLE;
  380.  
  381. /*
  382.  *  space for zoomed window pos & size
  383.  */
  384. WORD zoompos[4];
  385.  
  386. #define P_WA_Left       0
  387. #define P_WA_Top        1
  388. #define P_WA_Width      2
  389. #define P_WA_Height     3
  390. #define P_WA_Title      6
  391. #define P_WA_PubScreen  7
  392. #define P_WA_Gadgets    8
  393. struct TagItem mywindowtag[] = {
  394.     WA_Left,        0l,
  395.     WA_Top,         20l,
  396.     WA_Width,       400l,
  397.     WA_Height,      150l,
  398.     WA_IDCMP,       IDCMP_CLOSEWINDOW | BUTTONIDCMP | IDCMP_REFRESHWINDOW | IDCMP_VANILLAKEY,
  399.     WA_Flags,       WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH |
  400.                     WFLG_ACTIVATE | WFLG_RMBTRAP,
  401.     WA_Title,       (ULONG)windowtitle,
  402.     WA_PubScreen,   0l,
  403.     WA_Gadgets,     0l,
  404.     WA_Zoom,        (ULONG)zoompos,
  405.     WA_AutoAdjust,  FALSE,
  406.     TAG_END
  407.     };
  408.  
  409. char msg_seconds[] = MSG_SECONDS;
  410. char msg_key[]     = MSG_KEY;
  411. char msg_hide[]    = MSG_HIDE;
  412. char msg_quit[]    = MSG_QUIT;
  413.  
  414. /*
  415.  *  gadget definitions
  416.  */
  417. #define DBL_INTERWIDTH  (INTERWIDTH << 1)
  418. #define DBL_INTERHEIGHT (INTERHEIGHT << 1)
  419.  
  420. #define GAD_SECONDS 6
  421. #define GAD_KEY     7
  422. #define GAD_HIDE    8
  423. #define GAD_QUIT    9
  424.  
  425. struct Gadget *gad_seconds;
  426. struct Gadget *gad_key;
  427.  
  428. /********************************************************************
  429.  *                             functions                            *
  430.  ********************************************************************/
  431.  
  432. /*
  433.  *  request(): a glue routine to EasyRequest as simple as printf plus
  434.  *             titlestring, gadgettexts
  435.  *
  436.  *  Input: char *title:         pointer to the title of the requester
  437.  *         char *gadgets:       pointer to gadgettext
  438.  *         char *text:          text displayed in requester
  439.  *
  440.  *  Result: same as EasyrequestArgs()
  441.  *
  442.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  443.  */
  444. long request(char *title, char *gadgets, char *text, ...)
  445. {
  446.     /*
  447.      *  structure textreq only needed in this function, so hide it here
  448.      *  must be static, in order to be initialized only once
  449.      */
  450.     static struct EasyStruct textreq = {
  451.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  452.         0l,                         /* ULONG es_Flags           */
  453.         NULL,                       /* UBYTE *es_Title          */
  454.         NULL,                       /* UBYTE *es_TextFormat     */
  455.         NULL,                       /* UBYTE *es_GadgetFormat   */
  456.         };
  457.     va_list ap;
  458.     long rc;
  459.  
  460.     /*
  461.      *  get start of variable arguments
  462.      */
  463.     va_start(ap, text);
  464.  
  465.     /*
  466.      *  update textreq
  467.      */
  468.     textreq.es_Title = (UBYTE *)title;
  469.     textreq.es_TextFormat = (UBYTE *)text;
  470.     textreq.es_GadgetFormat = (UBYTE *)gadgets;
  471.  
  472.     /*
  473.      *  win may be NULL
  474.      */
  475.     rc = EasyRequestArgs(win, &textreq, NULL, ap);
  476.  
  477.     va_end(ap);
  478.  
  479.     return(rc);
  480. }
  481.  
  482. /*
  483.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  484.  *                   if OpenLibrary() fails, to give the user a chance to
  485.  *                   copy the library to libs: and retry
  486.  *                   requires request(), see above
  487.  */
  488. struct Library *myopenlibrary(char *name, unsigned long version)
  489. {
  490.     static char errortext[] = MSG_LIBRARY_OPENERR;
  491.     struct Library *libptr;
  492.     long ok = TRUE;
  493.  
  494.     do {
  495.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  496.             if (IntuitionBase) ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
  497.             else ok = FALSE;
  498.             }
  499.         } while (!libptr && ok);
  500.  
  501.     return(libptr);
  502. }
  503.  
  504. void main(int argc, char *argv[])
  505. {
  506.     CxObj *customobj;
  507.     char *hotkey;
  508.     struct Message *msg;
  509.     long number;
  510.     short window = FALSE;
  511.  
  512.     #ifdef DEBUG
  513.     printf("\n" COM_TITLE " started.\n");
  514.     #endif
  515.  
  516.     if ((argc > 1) && (*argv[1] == '?')) {
  517.         /*
  518.          *  display help string
  519.          */
  520.         if (_Backstdout) {
  521.             Write(_Backstdout, helpstring, sizeof(helpstring) - 1l);
  522.             Close(_Backstdout);
  523.             }
  524.         return;
  525.         }
  526.     else if (argc && _Backstdout) Close(_Backstdout);
  527.  
  528.     /*
  529.      *  first we open intuition.library to be able to open an EasyRequest()
  530.      *  Problem: how tell we the user that intuition.library didn't open?
  531.      *           No intuition function will be available. I only tell him
  532.      *           in the docs, because writing any code for calling once pre-V37
  533.      *           AutoRequest() seems ridiculous, doesn't it?
  534.      */
  535.     if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37l)) {
  536.         /*
  537.          *  parse command line or tool types; we need icon.library therefore
  538.          */
  539.         if (IconBase = myopenlibrary("icon.library", 37l)) {
  540.             /*
  541.              * create tooltypes array (requires open icon.library!!!)
  542.              */
  543.             tooltypes = (char **)ArgArrayInit(argc, argv);
  544.             /*
  545.              *  what priority wishes the user for the broker?
  546.              */
  547.             newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
  548.             /*
  549.              *  check for a hotkey
  550.              */
  551.             hotkey = ArgString(tooltypes, CX_POPKEY, DEF_CX_POPKEY);
  552.             /*
  553.              *  get the user's prefered timeout
  554.              */
  555.             number = ArgInt(tooltypes, TT_TIMEOUT, DEF_TIMEOUT);
  556.             if (number < 1) timeoutseconds = 0;
  557.             else timeoutseconds = number;
  558.             timeoutperiod = timeoutseconds * 10;
  559.             /*
  560.              *  how many keypresses needed to blank?
  561.              */
  562.             number = ArgInt(tooltypes, TT_KEY, DEF_KEY);
  563.             if (number < 1) keypresses = 0;
  564.             else keypresses = number;
  565.             /*
  566.              *  how many seconds to wait before reblanking?
  567.              */
  568.             number = ArgInt(tooltypes, TT_REBLANK, DEF_REBLANK);
  569.             if (number < 1) reblank = 0;
  570.             else reblank = number;
  571.             /*
  572.              *  now we need a function of utility.library
  573.              */
  574.             if (UtilityBase = myopenlibrary("utility.library", 37l)) {
  575.                 /*
  576.                  *  shall we open our window at startup?
  577.                  */
  578.                 if (Stricmp(ArgString(tooltypes, CX_POPUP, DEF_CX_POPUP), YES) == 0l) window = TRUE;
  579.                 /*
  580.                  *  we don not need it any longer, so we close it
  581.                  */
  582.                 CloseLibrary(UtilityBase);
  583.                 } /* if UtilityBase */
  584.  
  585.             /*
  586.              *  in this case it doesn't matter if we couldn't open utility.library; no error processing required
  587.              *
  588.              *  now we need the commodities library (V37 of course, earlier versions may have problems)
  589.              */
  590.             if (CxBase = myopenlibrary("commodities.library", 37l)) {
  591.                 /*
  592.                  *  now let us open a message port for messages
  593.                  */
  594.                 if (msgport = CreateMsgPort()) {
  595.                     /*
  596.                      *  we have to copy the pointer to the port to newbroker
  597.                      */
  598.                     newbroker.nb_Port = msgport;
  599.                     cxsigflag = 1l << msgport->mp_SigBit;
  600.                     /*
  601.                      *  before we do anything else we try to open the broker
  602.                      *  if it fails it is most likely that this commodity is already
  603.                      *  running and we don't start again; if so we avoid opening
  604.                      *  many resources, which must be closed although we do nothing
  605.                      */
  606.                     if (broker = CxBroker(&newbroker, NULL)) {
  607.                         /*
  608.                          *  we need some more libraries
  609.                          */
  610.                         if (GfxBase = myopenlibrary("graphics.library", 37l)) {
  611.  
  612.                             if (GadToolsBase = myopenlibrary("gadtools.library", 37l)) {
  613.                                 /*
  614.                                  *  now we create the three filter objects
  615.                                  */
  616.                                 if (timerfilter = CxFilter(NULL)) {
  617.  
  618.                                     SetFilterIX(timerfilter, &timerix);
  619.                                     AttachCxObj(broker, timerfilter);
  620.  
  621.                                     if (mousefilter = CxFilter(NULL)) {
  622.  
  623.                                         SetFilterIX(mousefilter, &mouseix);
  624.                                         AttachCxObj(broker, mousefilter);
  625.  
  626.                                         if (keyfilter = CxFilter(NULL)) {
  627.  
  628.                                             SetFilterIX(keyfilter, &keyix);
  629.                                             AttachCxObj(broker, keyfilter);
  630.                                             /*
  631.                                              *  the custom object shall signal our task
  632.                                              *  therefore we need a signal and a pointer to our task
  633.                                              */
  634.                                             if ((signal = (long)AllocSignal(-1)) != -1) {
  635.  
  636.                                                 customsigflag = 1 << signal;
  637.  
  638.                                                 if (mytask = FindTask(NULL)) {
  639.                                                     /*
  640.                                                      *  no we create the three custom objects
  641.                                                      */
  642.                                                     if (customobj = CxCustom(timermon, 0l)) {
  643.  
  644.                                                         AttachCxObj(timerfilter, customobj);
  645.  
  646.                                                         if (customobj = CxCustom(mousemon, 0l)) {
  647.  
  648.                                                             AttachCxObj(mousefilter, customobj);
  649.  
  650.                                                             if (customobj = CxCustom(keymon, 0l)) {
  651.  
  652.                                                                 AttachCxObj(keyfilter, customobj);
  653.  
  654.                                                                 if (*hotkey && (hotkeyfilter = HotKey(hotkey, msgport, POP_KEY_ID))) {
  655.                                                                     AttachCxObj(broker, hotkeyfilter);
  656.                                                                     } /* if hotkey */
  657.  
  658.                                                                 if (simplesprite.posctldata = AllocMem(8l, MEMF_CHIP|MEMF_CLEAR)) {
  659.  
  660.                                                                     if (reblank) {
  661.                                                                         /*
  662.                                                                          *  if we shall reblank we need the timer.device
  663.                                                                          */
  664.                                                                         if (timereq = CreateIORequest(msgport, sizeof(struct timerequest))) {
  665.                                                                             if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timereq, 0l)) {
  666.                                                                                 /*
  667.                                                                                  *  timer.device didn't open
  668.                                                                                  */
  669.                                                                                 DeleteIORequest(timereq);
  670.                                                                                 timereq = NULL;
  671.                                                                                 reblank = 0;
  672.                                                                                 #ifdef DEBUG
  673.                                                                                 printf("main(): OpenDevice(" TIMERNAME ") failed!\n");
  674.                                                                                 #endif
  675.                                                                                 }
  676.                                                                             }
  677.                                                                         else {
  678.                                                                             reblank = 0;
  679.                                                                             #ifdef DEBUG
  680.                                                                             printf("main(): CreateIORequest() failed!\n");
  681.                                                                             #endif
  682.                                                                             }
  683.                                                                         }
  684.  
  685.                                                                     if (!CxObjError(timerfilter) &&
  686.                                                                         !CxObjError(mousefilter) &&
  687.                                                                         !CxObjError(keyfilter) &&
  688.                                                                         !(hotkeyfilter && CxObjError(hotkeyfilter))) {
  689.  
  690.                                                                         /*
  691.                                                                          *  deactivate timerfilter if timeoutseconds = 0
  692.                                                                          */
  693.                                                                         if (!timeoutseconds) ActivateCxObj(timerfilter, OFF);
  694.                                                                         /*
  695.                                                                          *  deactivate keyfilter if !keypresses
  696.                                                                          */
  697.                                                                         if (!keypresses) ActivateCxObj(keyfilter, OFF);
  698.                                                                         /*
  699.                                                                          *  activate our commodity
  700.                                                                          */
  701.                                                                         ActivateCxObj(broker, ON);
  702.                                                                         /*
  703.                                                                          * deactivate again, if no timeoutseconds and not keypresses
  704.                                                                          */
  705.                                                                         if (!timeoutseconds && !keypresses) ActivateCxObj(broker, OFF);
  706.                                                                         /*
  707.                                                                          *  now watch our numerous ports
  708.                                                                          */
  709.                                                                         processmessages(window);
  710.  
  711.                                                                         } /* if !CxObjError() */
  712.  
  713.                                                                     if (reblank && timereq) {
  714.                                                                         CloseDevice((struct IORequest *)timereq);
  715.                                                                         DeleteIORequest(timereq);
  716.                                                                         }
  717.  
  718.                                                                     FreeMem(simplesprite.posctldata, 8l);
  719.  
  720.                                                                     } /* if (simplesprite.posctldata = AllocMem(8l, MEMF_CHIP|MEMF_CLEAR) */
  721.  
  722.                                                                 } /* if keymon */
  723.  
  724.                                                             } /* if mousemon */
  725.  
  726.                                                         } /* if timermon */
  727.  
  728.                                                     } /* if mytask */
  729.  
  730.                                                 FreeSignal(signal);
  731.                                                 customsigflag = 0l;
  732.  
  733.                                                 } /* if signal */
  734.  
  735.                                             } /* if keyfilter */
  736.  
  737.                                         #ifdef DEBUG
  738.                                         else printf("main(): keyfilter = CxFilter() failed!\n");
  739.                                         #endif
  740.  
  741.                                         } /* if mousefilter */
  742.  
  743.                                     #ifdef DEBUG
  744.                                     else printf("main(): mousefilter = CxFilter() failed!\n");
  745.                                     #endif
  746.  
  747.                                     } /* if timerfilter */
  748.  
  749.                                 #ifdef DEBUG
  750.                                 else printf("main(): timerfilter = CxFilter() failed!\n");
  751.                                 #endif
  752.  
  753.                                 CloseLibrary(GadToolsBase);
  754.  
  755.                                 } /* if GadToolsBase */
  756.  
  757.                             CloseLibrary((struct Library *)GfxBase);
  758.  
  759.                             } /* if GfxBase */
  760.  
  761.                         DeleteCxObjAll(broker);
  762.  
  763.                         } /* if broker */
  764.  
  765.                     #ifdef DEBUG
  766.                     else printf("main(): CxBroker() failed!\n");
  767.                     #endif
  768.  
  769.                     /*
  770.                      *  delete our message port after replying all pending messages
  771.                      */
  772.                     while (msg = GetMsg(msgport)) ReplyMsg(msg);
  773.                     DeleteMsgPort(msgport);
  774.  
  775.                     #ifdef DEBUG
  776.                     printf("main(): msgport deleted!\n");
  777.                     #endif
  778.  
  779.                     } /* if msgport */
  780.  
  781.                 #ifdef DEBUG
  782.                 else printf("main(): msgport = CraeteMsgPort() failed!\n");
  783.                 #endif
  784.  
  785.                 CloseLibrary(CxBase);
  786.  
  787.                 } /* if CxBase */
  788.  
  789.             /*
  790.              *  free memory allocated by ArgArrayInit()
  791.              */
  792.             ArgArrayDone();
  793.  
  794.             CloseLibrary(IconBase);
  795.  
  796.             } /* if IconBase */
  797.  
  798.         CloseLibrary((struct Library *)IntuitionBase);
  799.  
  800.         } /* if IntuitionBase */
  801.  
  802. } /* main() */
  803.  
  804. void processmessages(short window)
  805. {
  806.     struct Message *msg;
  807.     unsigned long sigreceived;
  808.     unsigned long msgtype;
  809.     unsigned long msgid;
  810.     unsigned short quit = FALSE;
  811.  
  812.     if (window) command(CCMD_OPENWINDOW);
  813.  
  814.     while (!quit) {
  815.  
  816.         sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag | customsigflag | idcmpsigflag);
  817.  
  818.         if (sigreceived & customsigflag) {
  819.             /*
  820.              *  one of our custom commodities objects signalled us
  821.              */
  822.             if (blankrequest == BLANK) blankmouse(NORMAL);
  823.             else unblankmouse();
  824.             }
  825.  
  826.         if (sigreceived & cxsigflag) {
  827.             /*
  828.              *  a message at our message-port
  829.              */
  830.             while (msg = (struct Message *)GetMsg(msgport)) {
  831.                 /*
  832.                  *  check if it is the reply from the timer.device
  833.                  */
  834.                 if (msg == (struct Message *)timereq) {
  835.                     /*
  836.                      *  the message from the timer.device tells us: reblank the mouse!
  837.                      */
  838.                     #ifdef DEBUG
  839.                     printf("processmessages(): timer told to reblank!\n");
  840.                     #endif
  841.                     blankmouse(FORCE);
  842.                     }
  843.                 else {
  844.                     /*
  845.                      *  no reply from timer.device; we have to reply
  846.                      */
  847.                     msgid = CxMsgID((CxMsg *)msg);
  848.                     msgtype = CxMsgType((CxMsg *)msg);
  849.  
  850.                     ReplyMsg(msg);
  851.  
  852.                     switch (msgtype) {
  853.  
  854.                         case CXM_IEVENT:
  855.                             if (msgid == POP_KEY_ID) command(CCMD_OPENWINDOW);
  856.                             break;
  857.  
  858.                         case CXM_COMMAND:
  859.                             switch (msgid) {
  860.  
  861.                                 case CXCMD_KILL:
  862.                                     quit = command(CCMD_QUIT);
  863.                                     break;
  864.  
  865.                                 case CXCMD_DISABLE:
  866.                                     ActivateCxObj(broker, OFF);
  867.                                     unblankmouse();
  868.                                     break;
  869.  
  870.                                 case CXCMD_ENABLE:
  871.                                     ActivateCxObj(broker, ON);
  872.                                     break;
  873.  
  874.                                 case CXCMD_UNIQUE:
  875.                                 case CXCMD_APPEAR:
  876.                                     command(CCMD_OPENWINDOW);
  877.                                     break;
  878.  
  879.                                 case CXCMD_DISAPPEAR:
  880.                                     command(CCMD_CLOSEWINDOW);
  881.                                     break;
  882.  
  883.                                 }
  884.                             break;
  885.  
  886.                         } /* switch msgtype */
  887.  
  888.                     } /* if (msg != timerreq) */
  889.  
  890.                 } /* while CxMsg */
  891.  
  892.             } /* if (sigreceived & cxsigflag) */
  893.  
  894.         if (sigreceived & idcmpsigflag) {
  895.  
  896.             APTR *object;
  897.             ULONG class;
  898.             UWORD code;
  899.  
  900.             while (idcmpport && (msg = (struct Message *)GT_GetIMsg(idcmpport))) {
  901.                 /*
  902.                  *  handle IDCMP messages
  903.                  */
  904.                 class    = ((struct IntuiMessage *)msg)->Class;
  905.                 code     = ((struct IntuiMessage *)msg)->Code;
  906.                 object   = ((struct IntuiMessage *)msg)->IAddress;
  907.                 GT_ReplyIMsg((struct IntuiMessage *)msg);
  908.  
  909.                 switch (class) {
  910.  
  911.                     case CLOSEWINDOW:
  912.                         command(CCMD_CLOSEWINDOW);
  913.                         break;
  914.  
  915.                     case REFRESHWINDOW:
  916.                         if (win) {
  917.                             GT_BeginRefresh(win);
  918.                             GT_EndRefresh(win, TRUE);
  919.                             }
  920.                         break;
  921.  
  922.                     case GADGETUP:
  923.                         if (object) quit = command((unsigned short)((struct Gadget *)object)->UserData);
  924.                         break;
  925.  
  926.                     case VANILLAKEY:
  927.                         switch (code) {
  928.  
  929.                             case 27:
  930.                             case MSG_HIDE_SCC:
  931.                             case MSG_HIDE_SCC + CASE_DIFF:
  932.                                         command(CCMD_CLOSEWINDOW);
  933.                                         break;
  934.  
  935.                             case MSG_QUIT_SCC:
  936.                             case MSG_QUIT_SCC + CASE_DIFF:
  937.                                         quit = command(CCMD_QUIT);
  938.                                         break;
  939.  
  940.                             case MSG_SECONDS_SCC:
  941.                             case MSG_SECONDS_SCC + CASE_DIFF:
  942.                                         command(CCMD_SECONDS_ACTIVATE);
  943.                                         break;
  944.  
  945.                             case MSG_KEY_SCC:
  946.                             case MSG_KEY_SCC + CASE_DIFF:
  947.                                         command(CCMD_KEYPRESSES_ACTIVATE);
  948.                                         break;
  949.  
  950.                             }
  951.                         break;
  952.  
  953.                     } /* switch class */
  954.  
  955.                 } /* while idcmp message */
  956.  
  957.             } /* if (sigreceived & idcmpsigflag) */
  958.  
  959.         if (sigreceived & SIGBREAKF_CTRL_C) {
  960.             /*
  961.              *  someone sent us a CTRL-C: we must go home now
  962.              */
  963.             quit = command(CCMD_QUIT);
  964.             }
  965.  
  966.         } /* while !quit */
  967.  
  968.     /*
  969.      *  we are going home; first we deactivate the broker, ...
  970.      */
  971.     ActivateCxObj(broker, OFF);
  972.     #ifdef DEBUG
  973.     printf("processmessages(): leaving processmessages(), broker disabled\n");
  974.     #endif
  975.     /*
  976.      *  ...then we close the window...
  977.      */
  978.     closewindow();
  979.     unblankmouse();
  980. }
  981.  
  982. unsigned short command(unsigned short cmd)
  983. {
  984.     unsigned short quit = FALSE;
  985.  
  986.     #ifdef DEBUG
  987.     printf("command(): command = %ld\n", cmd);
  988.     #endif
  989.  
  990.     switch(cmd) {
  991.  
  992.         case CCMD_NOP:
  993.             break;
  994.  
  995.         case CCMD_QUIT:
  996.             quit = TRUE;
  997.             break;
  998.  
  999.         case CCMD_SECONDS:
  1000.             getseconds();
  1001.             break;
  1002.  
  1003.         case CCMD_SECONDS_ACTIVATE:
  1004.             if (win) ActivateGadget(gad_seconds, win, NULL);
  1005.             break;
  1006.  
  1007.         case CCMD_KEYPRESSES:
  1008.             getkeypresses();
  1009.             break;
  1010.  
  1011.         case CCMD_KEYPRESSES_ACTIVATE:
  1012.             if (win) ActivateGadget(gad_key, win, NULL);
  1013.             break;
  1014.  
  1015.         case CCMD_OPENWINDOW:
  1016.             if (!openwindow()) request(COM_NAME ":", RESUME_GADGETS, MSG_WINDOW_OPENERR);
  1017.             break;
  1018.  
  1019.         case CCMD_CLOSEWINDOW:
  1020.             getseconds();
  1021.             getkeypresses();
  1022.             closewindow();
  1023.             break;
  1024.  
  1025.         } /* switch (command) */
  1026.  
  1027.     return(quit);
  1028. }
  1029.  
  1030. /************************
  1031.  *  commodity functions *
  1032.  ************************/
  1033.  
  1034. void __saveds timermon(void)
  1035. {
  1036.     if (++timeout >= timeoutperiod) {
  1037.  
  1038.         blankrequest = BLANK;
  1039.         if (mytask && customsigflag) Signal(mytask, customsigflag);
  1040.         timeout = 0;
  1041.  
  1042.         #ifdef DEBUG
  1043.         printf(COM_NAME ": timermon blanked\n");
  1044.         #endif
  1045.  
  1046.         }
  1047. }
  1048.  
  1049. void __saveds mousemon(void)
  1050. {
  1051.     timeout = 0;
  1052.     keys    = 0;
  1053.  
  1054.     if (MOUSEBLANKED && blankrequest != UNBLANK) {
  1055.         blankrequest = UNBLANK;
  1056.         if (mytask && customsigflag) Signal(mytask, customsigflag);
  1057.         #ifdef DEBUG
  1058.         printf(COM_NAME ": mousemon unblanked\n");
  1059.         #endif
  1060.         }
  1061. }
  1062.  
  1063. void __saveds keymon(void)
  1064. {
  1065.     if (++keys >= keypresses) {
  1066.  
  1067.         if (MOUSENOTBLANKED) {
  1068.  
  1069.             blankrequest = BLANK;
  1070.             if (mytask && customsigflag) Signal(mytask, customsigflag);
  1071.             #ifdef DEBUG
  1072.             printf(COM_NAME ": keymon blanked\n");
  1073.             #endif
  1074.             }
  1075.  
  1076.         }
  1077. }
  1078.  
  1079. /*********************
  1080.  *  window functions *
  1081.  *********************/
  1082.  
  1083. struct Screen *lockfrontpubscr(void)
  1084. {
  1085.     struct Screen *scr;
  1086.     struct Screen *pubscr = NULL;
  1087.     struct List *pslist;
  1088.     struct PubScreenNode *psnode;
  1089.     unsigned long lock;
  1090.     unsigned short screentype;
  1091.  
  1092.     lock = LockIBase(0l);
  1093.  
  1094.     if (scr = IntuitionBase->FirstScreen) {
  1095.  
  1096.         screentype = scr->Flags & SCREENTYPE;
  1097.  
  1098.         UnlockIBase(lock);
  1099.  
  1100.         if (screentype == PUBLICSCREEN || screentype == WBENCHSCREEN) {
  1101.  
  1102.             if (pslist = LockPubScreenList()) {
  1103.  
  1104.                 for (psnode = (struct PubScreenNode *)pslist->lh_Head;
  1105.                      psnode->psn_Node.ln_Succ && (psnode->psn_Screen != scr);
  1106.                      psnode = (struct PubScreenNode *)psnode->psn_Node.ln_Succ);
  1107.  
  1108.                 if (psnode && (psnode->psn_Screen == scr) && !(psnode->psn_Flags & PSNF_PRIVATE)) {
  1109.  
  1110.                     pubscr = LockPubScreen(psnode->psn_Node.ln_Name);
  1111.  
  1112.                     }
  1113.  
  1114.                 UnlockPubScreenList();
  1115.  
  1116.                 }
  1117.  
  1118.             }
  1119.  
  1120.         }
  1121.  
  1122.     else UnlockIBase(lock);
  1123.  
  1124.     if (pubscr && ((pubscr->Width < 640) || (pubscr->Height < 200))) {
  1125.         UnlockPubScreen(NULL, pubscr);
  1126.         pubscr = NULL;
  1127.         }
  1128.  
  1129.     /*
  1130.      *  no locked screen yet, try default public screen
  1131.      */
  1132.     if (!pubscr) pubscr = LockPubScreen(NULL);
  1133.  
  1134.     return(pubscr);
  1135. }
  1136.  
  1137. long openwindow(void)
  1138. {
  1139.     struct DimensionInfo di;
  1140.     struct Rectangle *rect;
  1141.     unsigned long vpmid;
  1142.     long ok;
  1143.  
  1144.     if (win) {
  1145.         /*
  1146.          *  dont't open window but pop it to front, unzip it
  1147.          *
  1148.          *  unzip window if zipped
  1149.          */
  1150.         if (win->Height < mywindowtag[P_WA_Height].ti_Data) ZipWindow(win);
  1151.         /*
  1152.          *  window to front
  1153.          */
  1154.         WindowToFront(win);
  1155.         /*
  1156.          *  activate window
  1157.          */
  1158.         if (win != IntuitionBase->ActiveWindow) ActivateWindow(win);
  1159.         /*
  1160.          *  screen to front
  1161.          */
  1162.         if (win->WScreen != IntuitionBase->FirstScreen) ScreenToFront(win->WScreen);
  1163.  
  1164.         ok = TRUE;
  1165.         }
  1166.  
  1167.     else {
  1168.         /*
  1169.          *  lock the default public screen
  1170.          */
  1171.         if (scr = lockfrontpubscr()) {
  1172.             /*
  1173.              *  GetVisualInfo() for gadtools
  1174.              */
  1175.             if (vi = GetVisualInfo(scr, TAG_DONE)) {
  1176.                 /*
  1177.                  *  update some window information
  1178.                  */
  1179.                 mywindowtag[P_WA_Width].ti_Data = zoompos[2] =
  1180.                     TextLength(&scr->RastPort, (STRPTR)windowtitle, sizeof(windowtitle) - 1l) + 100;
  1181.                 mywindowtag[P_WA_Height].ti_Data = zoompos[3] =
  1182.                     scr->WBorTop + scr->RastPort.TxHeight + 1;
  1183.                 /*
  1184.                  *  create all gadgets:
  1185.                  *
  1186.                  *  this function may also change the width and height of our window
  1187.                  */
  1188.                 if (createallgadgets(&gadgetlist, vi, scr,
  1189.                                      &mywindowtag[P_WA_Height].ti_Data,
  1190.                                      &mywindowtag[P_WA_Width].ti_Data)) {
  1191.                     /*
  1192.                      *  center the window in the visible box of the screen
  1193.                      */
  1194.                     if ((vpmid = GetVPModeID(&scr->ViewPort )) != INVALID_ID) {
  1195.  
  1196.                         GetDisplayInfoData(0, (UBYTE *)&di, sizeof(struct DimensionInfo), DTAG_DIMS, vpmid);
  1197.                         rect = &di.TxtOScan;
  1198.                         zoompos[0] = mywindowtag[P_WA_Left].ti_Data =
  1199.                             (scr->LeftEdge < 0 ? -scr->LeftEdge : 0) +
  1200.                             ((min((rect->MaxX - rect->MinX + 1), scr->Width) -
  1201.                               mywindowtag[P_WA_Width].ti_Data) >> 1);
  1202.                         zoompos[1] = mywindowtag[P_WA_Top].ti_Data =
  1203.                             (scr->TopEdge < 0 ? -scr->TopEdge : 0) +
  1204.                             ((min((rect->MaxY - rect->MinY + 1), scr->Height) -
  1205.                               mywindowtag[P_WA_Height].ti_Data) >> 1);
  1206.  
  1207.                         }
  1208.  
  1209.                     mywindowtag[P_WA_PubScreen].ti_Data = (ULONG)scr;
  1210.  
  1211.                     mywindowtag[P_WA_Gadgets].ti_Data = (ULONG)gadgetlist;
  1212.                     if (win = OpenWindowTagList(NULL, mywindowtag)) {
  1213.                         /*
  1214.                          *  save IDCMP port
  1215.                          */
  1216.                         idcmpport = win->UserPort;
  1217.                         idcmpsigflag = 1L << idcmpport->mp_SigBit;
  1218.  
  1219.                         GT_RefreshWindow(win, NULL);
  1220.  
  1221.                         /*
  1222.                          *  switch screen to front
  1223.                          */
  1224.                         if (win->WScreen != IntuitionBase->FirstScreen) ScreenToFront(win->WScreen);
  1225.  
  1226.                         ok = TRUE;
  1227.  
  1228.                         } /* if (win = OpenWindowTagList(NULL, mywindowtag)) */
  1229.  
  1230.                     #ifdef DEBUG
  1231.                     else printf("openwindow(): OpenWindowTagList() failed!\n");
  1232.                     #endif
  1233.  
  1234.                     } /* if (createallgadgets() */
  1235.  
  1236.                 #ifdef DEBUG
  1237.                 else printf("openwindow(): createallgadgets() failed!\n");
  1238.                 #endif
  1239.  
  1240.                 } /*  if (vi = GetVisualInfo(scr, TAG_DONE)) */
  1241.  
  1242.             #ifdef DEBUG
  1243.             else printf("openwindow(): GetVisualInfo() failed!\n");
  1244.             #endif
  1245.  
  1246.             } /* if (scr = LockPubScreen(NULL)) */
  1247.  
  1248.         #ifdef DEBUG
  1249.         else printf("openwindow(): LockPubScr() failed!\n");
  1250.         #endif
  1251.  
  1252.         if (!ok) {
  1253.             /*
  1254.              *  window could not be opened - free all resources
  1255.              */
  1256.             closewindow();
  1257.             }
  1258.  
  1259.         } /* if (!win) */
  1260.  
  1261.     return(ok);
  1262. }
  1263.  
  1264. void closewindow(void)
  1265. {
  1266.     if (win) {
  1267.         /*
  1268.          *  now close the window
  1269.          */
  1270.         CloseWindow(win);
  1271.         win = NULL;
  1272.         idcmpport = NULL;
  1273.         idcmpsigflag = 0l;
  1274.         }
  1275.  
  1276.     if (gadgetlist) {
  1277.         FreeGadgets(gadgetlist);
  1278.         gadgetlist = NULL;
  1279.         }
  1280.  
  1281.     if (vi) {
  1282.         FreeVisualInfo(vi);
  1283.         vi = NULL;
  1284.         }
  1285.  
  1286.     if (scr) {
  1287.         UnlockPubScreen(NULL, scr);
  1288.         scr = NULL;
  1289.         }
  1290.  
  1291. }
  1292.  
  1293. void getseconds(void)
  1294. {
  1295.     long number;
  1296.  
  1297.     if (win) {
  1298.  
  1299.         if ((number = ((struct StringInfo *)gad_seconds->SpecialInfo)->LongInt) > 0) {
  1300.             /*
  1301.              *  input value ok
  1302.              */
  1303.             timeoutseconds = number;
  1304.             timeoutperiod  = timeoutseconds * 10;
  1305.             timeout = 0;
  1306.  
  1307.             if (MOUSENOTBLANKED) {
  1308.                 /*
  1309.                  *  activate timerfilter if mouse isn't blanked
  1310.                  */
  1311.                 ActivateCxObj(timerfilter, ON);
  1312.                 #ifdef DEBUG
  1313.                 printf("getseconds(): timerfilter enabled\n");
  1314.                 #endif
  1315.                 }
  1316.             }
  1317.  
  1318.         else {
  1319.             /*
  1320.              *  value given was < 1
  1321.              */
  1322.             timeoutseconds = timeout = 0;
  1323.             /*
  1324.              *  disable timerfilter
  1325.              */
  1326.             ActivateCxObj(timerfilter, OFF);
  1327.             #ifdef DEBUG
  1328.             printf("getseconds(): timerfilter disabled\n");
  1329.             #endif
  1330.  
  1331.             /*
  1332.              *  update gadget contents
  1333.              */
  1334.             GT_SetGadgetAttrs(gad_seconds, win, NULL, GTIN_Number, timeoutseconds, TAG_END);
  1335.  
  1336.             }
  1337.  
  1338.         } /* if win */
  1339.  
  1340. }
  1341.  
  1342. void getkeypresses(void)
  1343. {
  1344.     long number;
  1345.  
  1346.     if (win) {
  1347.  
  1348.         if ((number = ((struct StringInfo *)gad_key->SpecialInfo)->LongInt) > 0) {
  1349.             /*
  1350.              *  input value ok
  1351.              */
  1352.             keypresses = number;
  1353.             keys = 0;
  1354.  
  1355.             if (MOUSENOTBLANKED) {
  1356.                 /*
  1357.                  *  activate keyfilter if mouse isn't blanked
  1358.                  */
  1359.                 ActivateCxObj(keyfilter, ON);
  1360.                 #ifdef DEBUG
  1361.                 printf("getkeypresses(): keyfilter enabled\n");
  1362.                 #endif
  1363.                 }
  1364.             }
  1365.  
  1366.         else {
  1367.             /*
  1368.              *  value given was < 1
  1369.              */
  1370.             keypresses = 0;
  1371.  
  1372.             /*
  1373.              *  disable timerfilter
  1374.              */
  1375.             ActivateCxObj(keyfilter, OFF);
  1376.             #ifdef DEBUG
  1377.             printf("getkeypresses(): keyfilter disabled\n");
  1378.             #endif
  1379.  
  1380.             /*
  1381.              *  update gadget contents
  1382.              */
  1383.             GT_SetGadgetAttrs(gad_key, win, NULL, GTIN_Number, keypresses, TAG_END);
  1384.  
  1385.             }
  1386.  
  1387.         } /* if win */
  1388.  
  1389. }
  1390.  
  1391. /*
  1392.  *  createallgadgets(): create all gadgets and put required width and height
  1393.  *                      of window in height and width
  1394.  */
  1395. struct Gadget *createallgadgets(struct Gadget **glist, APTR vi, struct Screen *scr, ULONG *height, ULONG *width)
  1396. {
  1397.     static struct NewGadget ng;
  1398.     struct Gadget *gad;
  1399.     struct RastPort *rp;
  1400.     short buttonwidth;
  1401.     short gadtitlewidth;
  1402.     short stringgadgetwidth;
  1403.     short dummy;
  1404.  
  1405.     /*
  1406.      *  first get RastPort of screen to determine some TextLength()
  1407.      */
  1408.     rp = &scr->RastPort;
  1409.  
  1410.     /*
  1411.      *  maximum width of a button
  1412.      */
  1413.     buttonwidth = TextLength(rp, (STRPTR)&msg_hide[1], sizeof(msg_hide) - 2l);
  1414.     dummy       = TextLength(rp, (STRPTR)&msg_quit[1], sizeof(msg_quit) - 2l);
  1415.     buttonwidth = max(buttonwidth, dummy);
  1416.     buttonwidth += DBL_INTERWIDTH;
  1417.     /*
  1418.      *  check out if the window's width has to be enlarged
  1419.      */
  1420.     *width = max((buttonwidth << 1) + (DBL_INTERWIDTH + INTERWIDTH), *width);
  1421.     /*
  1422.      *  now the maximum length of the text left to the stringgadgets
  1423.      */
  1424.     gadtitlewidth = TextLength(rp, (STRPTR)&msg_seconds[1], sizeof(msg_seconds) - 2l);
  1425.     dummy         = TextLength(rp, (STRPTR)&msg_key[1], sizeof(msg_key) - 2l);
  1426.     gadtitlewidth = max(gadtitlewidth, dummy);
  1427.     /*
  1428.      *  calculate width of a stringgadet: I tried out that 6 times the width
  1429.      *  of the digit "0" gives a nice value for the integer gadget
  1430.      */
  1431.     stringgadgetwidth = TextLength(rp, (STRPTR)"000000", 6l);
  1432.     /*
  1433.      *  check out if the window's width has to be enlarged
  1434.      */
  1435.     *width = max(stringgadgetwidth + gadtitlewidth + DBL_INTERWIDTH + INTERWIDTH, *width);
  1436.     /*
  1437.      *  now create the gadgets
  1438.      */
  1439.     gad = CreateContext(glist);
  1440.     /*
  1441.      *  seconds gadget
  1442.      */
  1443.     ng.ng_TopEdge  = scr->WBorTop + rp->TxHeight + 1 + INTERHEIGHT;
  1444.     ng.ng_Width    = stringgadgetwidth;
  1445.     ng.ng_LeftEdge = ((*width - gadtitlewidth - stringgadgetwidth - INTERWIDTH) >> 1) +
  1446.                      gadtitlewidth + INTERWIDTH;
  1447.     ng.ng_Height        = rp->TxHeight + 4;
  1448.     ng.ng_GadgetText    = (UBYTE *)msg_seconds;
  1449.     ng.ng_TextAttr      = scr->Font;
  1450.     ng.ng_GadgetID      = GAD_SECONDS;
  1451.     ng.ng_Flags         = PLACETEXT_LEFT;
  1452.     ng.ng_VisualInfo    = vi;
  1453.     ng.ng_UserData      = (APTR)CCMD_SECONDS;
  1454.  
  1455.     gad_seconds = gad = CreateGadget(INTEGER_KIND, gad, &ng,
  1456.                                      GTIN_MaxChars, 3l,
  1457.                                      GTIN_Number, (ULONG)timeoutseconds,
  1458.                                      GT_Underscore, '_',
  1459.                                      TAG_DONE);
  1460.  
  1461.     /*
  1462.      *  key presses gadget
  1463.      */
  1464.     ng.ng_TopEdge    += ng.ng_Height + INTERHEIGHT;
  1465.     ng.ng_GadgetText  = (UBYTE *)msg_key;
  1466.     ng.ng_GadgetID    = GAD_KEY;
  1467.     ng.ng_UserData    = (APTR)CCMD_KEYPRESSES;
  1468.  
  1469.     gad_key = gad = CreateGadget(INTEGER_KIND, gad, &ng,
  1470.                                  GTIN_MaxChars, 3l,
  1471.                                  GTIN_Number, (ULONG)keypresses,
  1472.                                  GT_Underscore, '_',
  1473.                                  TAG_DONE);
  1474.  
  1475.     /*
  1476.      *  dummy now gets the spacing between the button gadgets
  1477.      */
  1478.     dummy = (*width - (buttonwidth << 1)) / 3;
  1479.  
  1480.     /*
  1481.      *  Hide gadget
  1482.      */
  1483.     ng.ng_TopEdge      += ng.ng_Height + INTERHEIGHT;
  1484.     ng.ng_Width         = buttonwidth;
  1485.     ng.ng_LeftEdge      = dummy;
  1486.     ng.ng_GadgetText    = (UBYTE *)msg_hide;
  1487.     ng.ng_GadgetID      = GAD_HIDE;
  1488.     ng.ng_Flags         = 0l;
  1489.     ng.ng_UserData      = (APTR)CCMD_CLOSEWINDOW;
  1490.  
  1491.     gad = CreateGadget(BUTTON_KIND, gad, &ng, GT_Underscore, '_', TAG_DONE);
  1492.  
  1493.     /*
  1494.      *  Quit gadget
  1495.      */
  1496.     ng.ng_LeftEdge     += ng.ng_Width + dummy;
  1497.     ng.ng_GadgetText    = (UBYTE *)msg_quit;
  1498.     ng.ng_GadgetID      = GAD_QUIT;
  1499.     ng.ng_UserData      = (APTR)CCMD_QUIT;
  1500.  
  1501.     gad = CreateGadget(BUTTON_KIND, gad, &ng, GT_Underscore, '_', TAG_DONE);
  1502.  
  1503.     *height = ng.ng_TopEdge + ng.ng_Height + scr->WBorBottom + INTERHEIGHT;
  1504.  
  1505.     return(gad);
  1506. }
  1507.  
  1508. /****************************
  1509.  *  the mouse blanking part *
  1510.  ****************************/
  1511.  
  1512. /*
  1513.  *  blank mouse if not already blanked or if mode == FORCE
  1514.  */
  1515. void blankmouse(short mode)
  1516. {
  1517.     #ifdef DEBUG
  1518.     short ok;
  1519.     #endif
  1520.  
  1521.     if (MOUSENOTBLANKED || mode == FORCE) {
  1522.  
  1523.         #ifdef DEBUG
  1524.         printf("blankmouse(): *** blanking mouse ***\n");
  1525.         #endif
  1526.  
  1527.         /*
  1528.          *  mouse blanking is done by freeing sprite #0
  1529.          */
  1530.         Forbid();
  1531.         FreeSprite(0);
  1532.  
  1533.         #ifdef DEBUG
  1534.         ok = GetSprite(&simplesprite, 0);
  1535.         #else
  1536.  
  1537.         GetSprite(&simplesprite, 0);
  1538.  
  1539.         #endif
  1540.  
  1541.         Permit();
  1542.  
  1543.         blankstatus = BLANKED;
  1544.  
  1545.         #ifdef DEBUG
  1546.         if (ok == -1) printf("blankmouse(): *** GetSprite failed ***\n");
  1547.         #endif
  1548.  
  1549.         if (mode != FORCE) {
  1550.             /*
  1551.              *  we require the mousefilter, activate it
  1552.              */
  1553.             ActivateCxObj(mousefilter, ON);
  1554.             #ifdef DEBUG
  1555.             printf("blankmouse(): mousefilter enabled\n");
  1556.             #endif
  1557.  
  1558.             /*
  1559.              *  timerfilter & keyfilter are obsolete
  1560.              */
  1561.             ActivateCxObj(timerfilter, OFF);
  1562.             ActivateCxObj(keyfilter, OFF);
  1563.             #ifdef DEBUG
  1564.             printf("blankmouse(): timerfilter & keyfilter disabled\n");
  1565.             #endif
  1566.             }
  1567.  
  1568.         /*
  1569.          *  start a new timerrequest
  1570.          */
  1571.         if (reblank && (mode == FORCE || !requestout)) {
  1572.             timereq->tr_node.io_Command = TR_ADDREQUEST;
  1573.             timereq->tr_time.tv_secs = reblank;
  1574.             timereq->tr_time.tv_micro = 0l;
  1575.             SendIO((struct IORequest *)timereq);
  1576.             requestout = TRUE;
  1577.             #ifdef DEBUG
  1578.             printf("blankmouse(): timerequest sent out!\n");
  1579.             #endif
  1580.             }
  1581.         }
  1582.  
  1583. }
  1584.  
  1585. /*
  1586.  *  unblank mouse if blanked
  1587.  */
  1588. void unblankmouse(void)
  1589. {
  1590.     blankstatus = UNBLANKED;
  1591.  
  1592.     if (timeoutseconds) {
  1593.         /*
  1594.          *  we have to activate the timerfilter
  1595.          */
  1596.         timeout = 0;
  1597.         ActivateCxObj(timerfilter, ON);
  1598.         #ifdef DEBUG
  1599.         printf("unblankmouse(): timerfilter enabled\n");
  1600.         #endif
  1601.         }
  1602.     else {
  1603.         /*
  1604.          *  mousefilter filter is obsolete, disable it
  1605.          */
  1606.         ActivateCxObj(mousefilter, OFF);
  1607.         #ifdef DEBUG
  1608.         printf("unblankmouse(): mousefilter disabled\n");
  1609.         #endif
  1610.         }
  1611.     if (keypresses) {
  1612.         /*
  1613.          *  we have to activate the keyfilter
  1614.          */
  1615.         keys = 0;
  1616.         ActivateCxObj(keyfilter, ON);
  1617.         #ifdef DEBUG
  1618.         printf("unblankmouse(): keyfilter enabled\n");
  1619.         #endif
  1620.         }
  1621.  
  1622.     /*
  1623.      *  abort the timerrequest if it is not home yet
  1624.      */
  1625.     if (requestout) {
  1626.         AbortIO((struct IORequest *)timereq);
  1627.         WaitIO((struct IORequest *)timereq);
  1628.         requestout = FALSE;
  1629.         #ifdef DEBUG
  1630.         printf("unblankmouse(): timereq aborted!\n");
  1631.         #endif
  1632.         }
  1633. }